import os
import time
import uuid
from DrissionPage import ChromiumPage, ChromiumOptions
from bs4 import BeautifulSoup
import sys
import traceback
from PyQt6.QtGui import QIcon, QPixmap
from PyQt6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QWidget,
                             QPushButton, QFileDialog, QLineEdit, QLabel, QTextEdit, QCheckBox, QGridLayout,
                             QHBoxLayout)
from PyQt6.QtCore import QThread, pyqtSignal, QDateTime, QByteArray, QBuffer, QIODevice, QSettings
from xml.etree import ElementTree as ET

# 获取脚本所在的目录
script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
icon_data = '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'


class Worker:
    def __init__(self, username=None, password=None, url_file_path=None, log_signal=None, is_Login=False, retry_input=1, time_sleep=120):
        self.config_path = F'{script_dir}\Config\config.xml'
        self.username = username
        self.password = password
        self.url_file_path = url_file_path  # 要查询的URL文本地址
        self.unique_id = str(uuid.uuid4()).replace('-', '')
        self.save_path = F'{script_dir}\下载_{self.unique_id}'
        self.log_signal = log_signal
        self.is_Login = is_Login
        self.retry_input = retry_input
        self.time_sleep = time_sleep

    def log(self, message):
        if self.log_signal:
            self.log_signal.emit(message)

    def read_chrmoe_path(self):
        """
        读取chrome配置文件路径
        :return:
        """
        chrome_path = ''
        try:
            # 打开文件并读取内容
            with open(F'{script_dir}/Config/chrome_path.txt', 'r', encoding='utf-8') as file:
                lines = file.readlines()
            # 遍历每一行，找到包含'chrome.exe'的行
            for line in lines:
                if 'chrome.exe' in line:
                    chrome_path = line.strip()
                    self.log(f'可执行文件路径读取成功：{chrome_path}')
                    break
            return chrome_path
        except:
            self.log('未找到chrome_path可执行文件路径')

    def chrom_page(self):
        """
        打开一个chrome浏览器
        :return: page对象
        """
        chrome_path = self.read_chrmoe_path()
        try:
            path = fr'{chrome_path}'
            co = ChromiumOptions().auto_port()
            co.set_browser_path(path)
            page = ChromiumPage(co)
            # 设置窗口最大化
            page.set.window.max()
            # 访问网页
            page.get('https://www.link114.cn/')
            return page
        except Exception as e:
            self.log(f'Chrome启动失败：{e}')
            with open('error_log.txt', 'a', encoding='utf-8') as log_file:
                log_file.write(str(e) + '\n')
                log_file.write(traceback.format_exc() + '\n')
            return self.chrom_page()

    def login(self, page, username, password):
        try:
            page.ele("x://span[@class='floatright member_info']//a").click()  # 点击登录
            page.ele('@name=username').input(username)  # 账号
            time.sleep(2)
            page.ele('@name=passwd').input(password)  # 密码
            time.sleep(2)
            page.ele("x://*[@id='do_submit']").click()  # 点击登录按钮
            time.sleep(2)
            page.ele('x:/html/body/div[2]/a').click()  # 登录成功后进入主页
            time.sleep(2)
            return page
        except Exception as e:
            self.log(f'登录出现异常:{e}')
            with open('error_log.txt', 'a', encoding='utf-8') as log_file:
                log_file.write(str(e) + '\n')
                log_file.write(traceback.format_exc() + '\n')
            return page

    def split_txt_file(self, file_path, lines_per_file=500):
        """
        分割TXT到文件夹中
        :param file_path: 需要分割的TXT文件路径
        :param lines_per_file: 每个TXT中分割多少条数据
        :return: 包含完整路径的文件名列表
        """
        # 创建保存新文件的目录
        temp_dir = os.path.join(script_dir, 'Temp')
        if not os.path.exists(temp_dir):
            os.makedirs(temp_dir)
        output_dir = f'{script_dir}\Temp\{self.unique_id}'
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)
        with open(file_path, 'r', encoding='utf-8') as file:
            lines = file.readlines()
            # 计算需要创建的新文件数量
        num_files = (len(lines) + lines_per_file - 1) // lines_per_file
        # 分割文件并保存
        file_names = []  # 初始化一个空列表来保存文件名
        for i in range(num_files):
            start_idx = i * lines_per_file
            end_idx = min((i + 1) * lines_per_file, len(lines))
            file_contents = lines[start_idx:end_idx]
            # 构建新文件的名称
            file_name = f'split_file_{i + 1}.txt'
            file_path_new = os.path.join(output_dir, file_name)
            with open(file_path_new, 'w', encoding='utf-8') as new_file:
                new_file.writelines(file_contents)
                # 将文件名添加到列表中
            file_names.append(file_name)
            # 输出中文并返回包含新文件名的列表
        self.log(f"分割完成。在'{output_dir}'目录中创建了 {num_files} 个新的txt文件。")
        return [f'{output_dir}/' + name for name in file_names]  # 返回包含完整路径的文件名列表

    def read_txt_file(self, file_path):
        """
        读取TXT中的内容
        :param file_path: TXT文件路径
        :return: 文件内容
        """
        try:
            with open(file_path, 'r', encoding='utf-8') as file:
                content = file.read()
            return content
        except FileNotFoundError:
            self.log(f"文件未找到：{file_path}")
            return None
        except Exception as e:
            self.log(f"读取文件时发生错误：{e}")
            return None

    def load_config(self, xml_file):
        """
        解析XML配置文件，并返回元素的操作配置列表。
        :param xml_file: str，XML配置文件的路径。
        :return: list，包含所有元素的操作配置，每个配置为一个三元组 (name, xpath, enabled)。
        """
        tree = ET.parse(xml_file)  # 解析XML文件并获取根元素
        root = tree.getroot()
        actions = []  # 初始化一个空列表，用于存储所有元素的操作配置
        for elem in root.findall('element'):  # 遍历XML文件中所有的<element>元素
            name = elem.find('name').text  # 名称
            xpath = elem.find('xpath').text  # XPATH
            # 获取<element>中的<enabled>标签内容，判断是否启用点击操作
            enabled = elem.find('enabled').text.lower() == 'true'  # 将其转换为布尔值，'true' (不区分大小写) 为True，其余为False
            actions.append((name, xpath, enabled))  # 将名称、XPath路径和是否启用点击操作存储为一个元组，并添加到actions列表中
        # 返回包含所有元素配置的列表
        return actions

    def click_tijiao(self, page, content, config_file, flag):
        # input_html = page.ele('x://*[@id="ip_websites"]').input(content, clear=True)  # 输入域名
        # page.ele('x://*[@id="ip_websites"]').input(content, clear=True, by_js=True)  # 输入域名
        page.run_js_loaded("document.getElementById('ip_websites').value = arguments[0];", content)
        time.sleep(2)

        if flag == 1:
            page.ele('x:/html/body/div[3]/div[1]/p[1]/span').click()  # 全选
            time.sleep(1)
            page.ele('x:/html/body/div[3]/div[1]/p[1]/span').click()  # 全选
            time.sleep(1)

            # 加载XML配置文件
            actions = self.load_config(config_file)
            # 遍历配置文件中的动作并执行
            for name, xpath, enabled in actions:
                if enabled:
                    # self.log(f"点击 {name} ({xpath})")  # 输出到控制台，方便调试
                    element = page.ele(f'x:{xpath}')
                    element.click()
                    time.sleep(0.5)  # 根据需要添加延时

        time.sleep(2)
        page.ele('x://*[@id="tj"]/a').click()  # 点击提交按钮
        # 等待加载完成的循环
        while True:
            tbody_html = page.ele('x://*[@id="result_table"]/tbody').html
            soup = BeautifulSoup(tbody_html, "html.parser")
            all_tr = soup.find('tbody').find_all('tr')[1:]  # 排除表头
            loading_gif_found = False
            for tr in all_tr:
                for td in tr.find_all('td'):
                    if '/template/images/loading.gif' in str(td):
                        loading_gif_found = True
                        break
                if loading_gif_found:
                    break
            if not loading_gif_found:
                break
            time.sleep(3)

    def click_recheck(self, page):
        """
        重查失败
        :param page:
        :return:
        """
        page.ele('x://*[@id="float_box"]/div[2]/a/span').click()  # 点击提交按钮
        time.sleep(3)

        tbody_html = page.ele('x://*[@id="result_table"]/tbody').html
        if '重查' in tbody_html or '失败' in tbody_html:
            while True:
                tbody_html = page.ele('x://*[@id="result_table"]/tbody').html
                soup = BeautifulSoup(tbody_html, "html.parser")
                all_tr = soup.find('tbody').find_all('tr')[1:]  # 排除表头
                # 检查所有td是否都不包含'/template/images/loading.gif'
                loading_gif_found = False
                for tr in all_tr:
                    for td in tr.find_all('td'):
                        if '/template/images/loading.gif' in str(td):
                            loading_gif_found = True
                            break  # 如果找到，则跳出内层循环
                    if loading_gif_found:
                        break  # 如果当前tr中有td包含指定字符串，则跳出外层循环
                    else:
                        pass
                # 检查是否所有td都不包含'/template/images/loading.gif'
                if not loading_gif_found:
                    break  # 如果所有td都不包含该字符串，则退出循环
                time.sleep(3)

    def click_save_path(self, page, txt_name):
        page.ele('x://*[@id="selectall"]/span').click()  # 点击全选
        time.sleep(2)
        mission = page.ele('x://*[@id="float_box"]/div[3]/a/span').click.to_download(save_path=self.save_path,
                                                                                     rename=f'{txt_name}')  # 点击导出
        mission.wait()
        time.sleep(5)

    def main(self):
        try:
            flag = 0  # 判断是第几次查询，如果是第一次以外的就不需要再次点击
            page = self.chrom_page()
            if self.is_Login:
                page = self.login(page, self.username, self.password)
                lines_per_file = 2000
            else:
                lines_per_file = 500
            txt_lists = self.split_txt_file(self.url_file_path, lines_per_file)
            for txt_path in txt_lists:
                flag = flag + 1

                content = self.read_txt_file(txt_path)

                self.log(f'<span style="color:Purple;">正在查询:{txt_path}</span>')
                self.click_tijiao(page, content, self.config_path, flag)
                self.log(f'<span style="color:green;">{txt_path}查询完成</span>')

                for i in range(self.retry_input):
                    self.log(f'<span style="color:Purple;">正在重查第{i + 1}次:{txt_path}</span>')
                    self.click_recheck(page)
                    self.log(f'<span style="color:green;">{txt_path}第{i + 1}次重查完成</span>')

                self.log(f'<span style="color:Purple;">准备导出:{txt_path}</span>')
                txt_name = os.path.basename(txt_path)
                self.click_save_path(page, txt_name)
                self.log(f'<span style="color:green;">{txt_path}导出完成</span>')
                self.log(f'<span style="color:black;">准备等待{self.time_sleep}秒进行下一个</span>')
                time.sleep(self.time_sleep)
            self.log('查询完毕！！！')
            time.sleep(10)
            page.close()
        except Exception as e:
            # try:
            #     page.close()
            # except Exception:
            #     pass
            self.log(f'<span style="color:red;">主程序出现异常(浏览器被异常关闭或者网络不稳定):{e}</span>')
            with open('error_log.txt', 'a', encoding='utf-8') as log_file:
                log_file.write(str(e) + '\n')
                log_file.write(traceback.format_exc() + '\n')
            # self.log('<span style="color:red;">尝试20S后重新打开网页</span>')
            # time.sleep(20)
            # return self.main()


class WorkerThread(QThread):
    log_signal = pyqtSignal(str)

    def __init__(self, username, password, url_file_path, is_Login, retry_input, time_sleep):
        super().__init__()
        self.worker = Worker(username, password, url_file_path, self.log_signal, is_Login, retry_input, time_sleep)

    def run(self):
        self.worker.main()


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('LINK114查询')
        self.setGeometry(100, 100, 750, 600)
        self.setup_icon()
        self.setup_ui()
        self.load_config()

    def setup_icon(self):
        icon_bytes = QByteArray.fromBase64(icon_data.encode('utf-8'))
        icon_buffer = QBuffer()
        icon_buffer.setData(icon_bytes)
        icon_buffer.open(QIODevice.OpenModeFlag.ReadOnly)
        pixmap = QPixmap()
        pixmap.loadFromData(icon_buffer.data())
        icon = QIcon(pixmap)
        self.setWindowIcon(icon)

    def setup_ui(self):
        layout = QVBoxLayout()

        # 文件路径部分
        file_path_layout = QVBoxLayout()
        self.file_path_label = QLabel('选择要查询的域名TXT:')
        file_path_layout.addWidget(self.file_path_label)
        self.file_path_input = QLineEdit()
        file_path_layout.addWidget(self.file_path_input)

        self.browse_button = QPushButton('浏览')
        self.browse_button.clicked.connect(self.browse_file)
        file_path_layout.addWidget(self.browse_button)

        layout.addLayout(file_path_layout)

        # 账号密码输入框
        account_password_layout = QHBoxLayout()
        account_label = QLabel('账号:')
        account_password_layout.addWidget(account_label)
        self.account_input = QLineEdit()
        self.account_input.setText('1003206180')
        account_password_layout.addWidget(self.account_input)

        password_label = QLabel('密码:')
        account_password_layout.addWidget(password_label)
        self.password_input = QLineEdit()
        self.password_input.setText('')
        account_password_layout.addWidget(self.password_input)

        retry_label = QLabel('重查次数:')
        account_password_layout.addWidget(retry_label)
        self.retry_input = QLineEdit()
        self.retry_input.setText('1')
        account_password_layout.addWidget(self.retry_input)

        time_sleep_label = QLabel('等待时间(s):')
        account_password_layout.addWidget(time_sleep_label)
        self.time_sleep = QLineEdit()
        self.time_sleep.setText('120')
        account_password_layout.addWidget(self.time_sleep)

        layout.addLayout(account_password_layout)

        # 开始按钮
        self.start_button = QPushButton('开始')
        self.start_button.clicked.connect(self.start_scraping)
        layout.addWidget(self.start_button)

        # 控制台输出
        self.console_output = QTextEdit()
        self.console_output.setReadOnly(True)
        layout.addWidget(self.console_output)

        # 添加新布局 - 复选框
        self.checkboxes_layout = QGridLayout()
        layout.addLayout(self.checkboxes_layout)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

    def load_config(self):
        try:
            global original_tree  # 使用全局变量来保存原始的 ElementTree
            # 加载配置文件
            config_path = f"{script_dir}/Config/config.xml"
            original_tree = ET.parse(config_path)  # 保存原始的 ElementTree
            root = original_tree.getroot()
            for idx, element in enumerate(root.findall('element')):
                name = element.find('name').text
                enabled = element.find('enabled').text == "true"
                checkbox = QCheckBox(name)
                checkbox.setChecked(enabled)
                checkbox.stateChanged.connect(
                    lambda state, cb=checkbox, el=element: self.on_checkbox_state_changed(state, cb, el))
                row = idx // 5  # 假设每行5个复选框
                col = idx % 5  # 假设每行5个复选框
                self.checkboxes_layout.addWidget(checkbox, row, col)
        except Exception as e:
            self.log(f'<span style="color:red;">配置文件Config读取异常:{e}</span>')

    def on_checkbox_state_changed(self, state, checkbox, element):
        # 当复选框状态改变时，更新 XML 文件
        enabled = state == 2  # Qt.Checked == 2
        element.find('enabled').text = str(enabled).lower()
        try:
            # 使用全局变量中的原始 ElementTree
            tree = original_tree
            tree.write(f"{script_dir}/Config/config.xml", encoding="UTF-8", xml_declaration=True)
            # self.log(f'{checkbox.text()} 的状态被更改为: {enabled}')
        except Exception as e:
            error_message = f"Error updating the configuration file: {str(e)}"
            self.log(error_message)
            with open('error_log.txt', 'a', encoding='utf-8') as log_file:
                log_file.write(error_message + '\n')
                log_file.write(traceback.format_exc() + '\n')

    def browse_file(self):
        file_path, _ = QFileDialog.getOpenFileName(self, "选择TXT文件", "", "TXT Files (*.txt)")
        if file_path:
            self.file_path_input.setText(file_path)

    def log(self, message):
        timestamp = QDateTime.currentDateTime().toString()
        self.console_output.append(
            f'<span style="color:blue;">[{timestamp}]</span> <span style="color:black;">{message}</span>')

    def start_scraping(self):
        file_path = self.file_path_input.text()  # 要查询的文件路径
        username = self.account_input.text()
        password = self.password_input.text()
        retry_input = int(self.retry_input.text())
        time_sleep = int(self.time_sleep.text())
        is_Login = False
        if username != '' and password != '':
            is_Login = True
        self.worker_thread = WorkerThread(username, password, file_path, is_Login, retry_input, time_sleep)
        self.worker_thread.log_signal.connect(self.log)
        self.worker_thread.start()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.log('账密为空默认一次查询500条')
    main_window.log('会员账号一次查询2000条')
    main_window.show()
    sys.exit(app.exec())
